<template>
  <div class="map-box">
    <div id="map-con" ref="mapCon"></div>
  </div>
</template>

<script>
import Map from "ol/Map";
import View from "ol/View";
import { Tile as TileLayer } from "ol/layer";
import Feature from "ol/Feature";
import Polygon, { circular } from "ol/geom/Polygon";
import { Vector as VectorSource, OSM } from "ol/source";
import { Style, Stroke, Fill } from "ol/style";
import { Vector as VectorLayer } from "ol/layer";
import { fromLonLat } from "ol/proj";
import * as proj from "ol/proj";
import Overlay from "ol/Overlay";
import { boundingExtent, getCenter } from "ol/extent";
import { getPointResolution } from 'ol/proj'
import { METERS_PER_UNIT } from 'ol/proj/Units'
import Circle from 'ol/geom/Circle'

export default {
  name: "polygon",
  data() {
    return {
      data: [
        [120, 30],
        [124, 30],
        [126, 33],
        [124, 36],
        [120, 36],
        [120, 30],
      ],
    };
  },
  created() {},
  mounted() {
    let data = this.data;
    // 创建要素
    let polygon = new Polygon([data]);
    
    polygon.applyTransform(proj.getTransform("EPSG:4326", "EPSG:3857"));
    const features = [
      new Feature({
        
        geometry: polygon,
      }),
    ];
    // 创建矢量数据源
    const source = new VectorSource({
      features,
    });
    // 创建样式
    const style = new Style({
      stroke: new Stroke({
        color: "#ff0000",
        width: 3,
        lineDash: [5],
      }),
      fill: new Fill({
        color: "rgba(255,255,255,0.9)",
      }),
    });
    // 创建矢量图层
    const areaLayer = new VectorLayer({
      source,
      style,
      zIndex: 100,
    });

    const map = new Map({
      view: new View({
        center: fromLonLat([120.771441, 30.756433]),
        zoom: 3,
        minZoom: 0,
        maxZoom: 18,
        constrainRotation: true,
      }),
      target: this.$refs.mapCon,
      layers: [
        new TileLayer({
          source: new OSM(),
        }),
      ],
    });

    map.addLayer(areaLayer);
    // 给多边形的中间显示自定义的名字
    // 获取范围的中心坐标
    let center = getCenter(this.getExtent(this.data));
    //显示名称
    let nameEl = document.createElement("div");
    nameEl.classList.add("name");
    nameEl.innerText = "我是名称";
    let nameOverlay = new Overlay({
      position: fromLonLat(center, "EPSG:3857"),
      element: nameEl,
      offset: [10, 10],
      positioning: "bottom-center",
    });
    map.addOverlay(nameOverlay);

    this.data.map = map;
    // ---------------------- 绘制一个圆
    const circleSource = this.renderRangeUseCircular(fromLonLat([130, 40]), 1000000);
    const circleStyle = new Style({
      stroke: new Stroke({
        color: "#00ff00",
        width: 3,
        lineDash: [5]
      }),
      fill: new Fill({
        color: 'rgba(0, 122, 204, 0.3)'
      })
    });
    let rangeLayer = new VectorLayer({
      source: circleSource,
      style: circleStyle,
      zIndex: 1000
    });
    map.addLayer(rangeLayer);
  },
  methods: {
    // 获取一个多边形的四个边界点，data:[[120.11997452699472, 30.314227730637967],[120.11997452699472, 30.314227730637967],...]
    getExtentCustom(data) {
      let minx = 99999999;
      let miny = 99999999;
      let maxx = -99999999999;
      let maxy = -99999999999;
      data.forEach((item) => {
        if (item[0] > maxx) {
          maxx = item[0];
        }
        if (item[0] < minx) {
          minx = item[0];
        }
        if (item[1] > maxy) {
          maxy = item[1];
        }
        if (item[1] < miny) {
          miny = item[1];
        }
      });
      return [Number(minx), Number(miny), Number(maxx), Number(maxy)];
    },
    // 也可以直接使用工具方法：boundingExtent
    getExtent(data) {
      return boundingExtent(data);
    },
    // 绘制圆 使用 circular绘制
    renderRangeUseCircular(center, radius) {
      const features = [];
      features.push(
        new Feature({
          geometry: new Circle(center, radius),
        })
      );
      return new VectorSource({
        features,
      });
    },
    // 绘制圆 使用 circle
    renderRangeUseCircle(center, projection = "EPSG:4326", radius) {
      const view = map.getView();
      const resolutionAtEquator = view.getResolution();
      const pointResolution = getPointResolution(
        projection,
        resolutionAtEquator,
        center,
        METERS_PER_UNIT.m
      );
      const resolutionFactor = resolutionAtEquator / pointResolution;
      radius = (radius / METERS_PER_UNIT.m) * resolutionFactor;
      const circle = new Circle(center, radius);
      const circleFeature = new Feature(circle);
      const vectorSource = new VectorSource({
        projection: projection,
      });
      vectorSource.addFeature(circleFeature);
      return vectorSource;
    }
   
  },
};
</script>

<style>
#map-con {
  height: 90vh;
}

.name {
  width: 100px;
  height: 30px;
  text-align: center;
  color: red;
}
</style>